cmake_minimum_required(VERSION 3.20)

project(libosmscout VERSION 1.1.1 LANGUAGES C CXX)
set(OSMSCOUT_LIBRARY_VERSION 1.1.1)

# If we are called from conan, include and activate it cmake additions
if(EXISTS ${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
  message("Loading conan definitions...")
  include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
  conan_basic_setup()
endif()

# global settings
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_MACOSX_RPATH 1)
set(CMAKE_VERBOSE_MAKEFILE OFF)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/" "$ENV{QTDIR}" "${QTDIR}" "$ENV{QTDIR}/lib/cmake" "${QTDIR}/lib/cmake")
if(NOT CMAKE_DEBUG_POSTFIX)
  if(APPLE)
    set(CMAKE_DEBUG_POSTFIX _debug)
  else()
    set(CMAKE_DEBUG_POSTFIX d)
  endif()
endif()

set(OSMSCOUT_BASE_DIR_SOURCE ${CMAKE_CURRENT_SOURCE_DIR})
set(OSMSCOUT_BASE_DIR_BUILD ${CMAKE_CURRENT_BINARY_DIR})

#include_directories(${OSMSCOUT_BASE_DIR_BUILD}/include)

set_property(GLOBAL PROPERTY USE_FOLDERS ON)

## Pre-feature options
option(QT_VERSION_PREFERRED "preferred Qt version, if multiple version are available. Value can be 5 or 6")

option(OSMSCOUT_BUILD_IMPORT_TOOL_FOR_DISTRIBUTION "Import tool for distribution" OFF)
if(APPLE)
  option(OSMSCOUT_BUILD_FRAMEWORKS "Enable build of libraries as frameworks" ON)
endif()

# options for extra debugging of map renderer
option(OSMSCOUT_DEBUG_LABEL_LAYOUTER "Print extra debug messages during label layouting" OFF)
option(OSMSCOUT_DEBUG_GROUNDTILES "Print extra debug messages while rendering ground tiles" OFF)

# options for extra debugging of import
option(OSMSCOUT_DEBUG_COASTLINE "Print extra debug messages while importing coastline" OFF)
option(OSMSCOUT_DEBUG_TILING "Print extra debug messages related with map tiles" OFF)

# options for extra debugging of routing
option(OSMSCOUT_DEBUG_ROUTING "Print extra debug messages while routing" OFF)

if(IOS)
  set(BUILD_SHARED_LIBS OFF CACHE INTERNAL "" FORCE)
else()
  option(BUILD_SHARED_LIBS "Shared libraries" ON)
endif()

# default build type
if(CMAKE_BUILD_TYPE STREQUAL "")
  set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build, options are: None (CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." FORCE)
endif()

# check minimal compiler
if(MSVC)
  if(MSVC_VERSION LESS 1900)
    message(FATAL_ERROR "For minimal support of C++17 at least Visual Studio 2015 is required!")
  endif()
endif()
# TODO: check gcc, clang, etc. version for C++17

# feature detection (libraries, header, etc.)
include(features)

# post-feature options
option(OSMSCOUT_BUILD_WITH_OPENMP "Enable OpenMP support" ${OPENMP_FOUND})
if(OSMSCOUT_BUILD_WITH_OPENMP)
  if(OPENMP_FOUND)
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
  else()
    message(FATAL_ERROR "OpenMP support enabled, but not supported")
  endif()
endif()

# compiler settings
include(CheckCXXCompilerFlag)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGXX OR CMAKE_COMPILER_IS_GNUCC)
  add_compile_options(-Wall -pedantic -Winit-self -Wno-overloaded-virtual -Wcast-qual -Wwrite-strings -Wextra -Wno-long-long)
  if(EMSCRIPTEN)
    add_compile_options(-Wno-warn-absolute-paths)
  elseif(NOT APPLE)
    add_compile_options(-Wno-unused-but-set-parameter)
  endif()
  if(UNIX)
    add_compile_options(-ldl -lm -lpthread)
  endif()

  if(NOT MINGW AND NOT APPLE)
    add_compile_options(-fPIC)
  endif()
endif()

if(MSVC)
  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /we4028")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:fast /wd4251 /MP")
  set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Oi")
  if(OSMSCOUT_PLATFORM_X64)
	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
  endif()
  add_definitions(-D_WIN32_WINNT=0x0A00 -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
endif()

if(MINGW OR MSYS)
  add_definitions(-D_WIN32_WINNT=0x0600)
  if(NOT OSMSCOUT_PLATFORM_X64)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=i686")
    # provide more addressable memory on win 32bit builds
    # see https://msdn.microsoft.com/en-us/library/aa366778
    set(CMAKE_EXE_LINKER_FLAGS "-Wl,--large-address-aware")
  endif ()
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive -fno-tree-slp-vectorize -Wno-error=cast-qual -Wno-unused-local-typedefs")
endif()

if((CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGXX OR CMAKE_COMPILER_IS_GNUCC) AND NOT MINGW)
  check_cxx_compiler_flag(-fvisibility=hidden OSMSCOUT_GCC_VISIBILITY)
  if(OSMSCOUT_GCC_VISIBILITY)
    execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE OSMSCOUT_GCC_VERSION)
    message(STATUS "Detected g++ ${OSMSCOUT_GCC_VERSION}")
    message(STATUS "Enabling GCC visibility flags")
    set(OSMSCOUT_GCC_VISIBILITY_FLAGS "-fvisibility=hidden")
    set(XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN "YES")
    string(TOLOWER "${CMAKE_BUILD_TYPE}" OSMSCOUT_BUILD_TYPE)

    if(OSMSCOUT_BUILD_TYPE STREQUAL "debug" AND OSMSCOUT_GCC_VERSION VERSION_LESS "4.2")
      message(STATUS "Skipping -fvisibility-inlines-hidden due to possible bug in g++ < 4.2")
    else()
      if(APPLE)
        message(STATUS "Skipping -fvisibility-inlines-hidden due to linker issues")
        set(XCODE_ATTRIBUTE_GCC_INLINES_ARE_PRIVATE_EXTERN[arch=x86_64] "YES")
      else()
        set(OSMSCOUT_VISIBILITY_FLAGS "${OSMSCOUT_GCC_VISIBILITY_FLAGS} -fvisibility-inlines-hidden")
        set(XCODE_ATTRIBUTE_GCC_INLINES_ARE_PRIVATE_EXTERN "YES")
      endif()
    endif()
  endif()
endif()

if(APPLE)
  if(IOS)
    set(CMAKE_SIZEOF_VOID_P 4)
    add_compile_options(-fobjc-arc -fembed-bitcode)
  else()
    add_compile_options(-fobjc-arc)
  endif()
  set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++20")
  set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
endif()

if(NOT BUILD_SHARED_LIBS)
  add_definitions(-DOSMSCOUT_STATIC)
endif()

include(ProjectConfig)
add_definitions(-D_USE_MATH_DEFINES)

# Test large file support
include(TestLargeFiles)
OPJ_TEST_LARGE_FILES(OPJ_HAVE_LARGEFILES)

# Qt DLLs
if(WIN32 AND TARGET Qt::qmake AND NOT TARGET Qt::windeployqt)
  get_target_property(_qt_qmake_location Qt::qmake IMPORTED_LOCATION)
  execute_process(
    COMMAND "${_qt_qmake_location}" -query QT_INSTALL_PREFIX
    RESULT_VARIABLE return_code
    OUTPUT_VARIABLE qt_install_prefix
    OUTPUT_STRIP_TRAILING_WHITESPACE
  )
  set(imported_location "${qt_install_prefix}/bin/windeployqt.exe")
  if(EXISTS ${imported_location})
    add_executable(Qt::windeployqt IMPORTED libosmscout-client/src/osmscoutclient/Empty.cpp)
    set_target_properties(Qt::windeployqt PROPERTIES IMPORTED_LOCATION ${imported_location})
  endif()
  option(OSMSCOUT_INSTALL_QT_DLL "Copies the DLLs from Qt to the installation directory" OFF)
  mark_as_advanced(OSMSCOUT_INSTALL_QT_DLL)
endif()

# components
set(OSMSCOUT_BUILD_CORE ON CACHE INTERNAL "" FORCE)
add_subdirectory(libosmscout)

option(OSMSCOUT_BUILD_IMPORT "Enable build of import library" ON)
if(OSMSCOUT_BUILD_IMPORT)
  add_subdirectory(libosmscout-import)
endif()

option(OSMSCOUT_BUILD_GPX "Enable build of gpx library" ON)
if(OSMSCOUT_BUILD_GPX)
  add_subdirectory(libosmscout-gpx)
endif()

set(OSMSCOUT_BUILD_MAP ON CACHE INTERNAL "" FORCE)
add_subdirectory(libosmscout-map)

if(LIBAGG_FOUND AND LIBAGGFT2_LIBRARIES AND FREETYPE_FOUND AND OSMSCOUT_BUILD_MAP)
  set(OSMSCOUT_BUILD_MAP_AGG_CACHE ON)
else()
  set(OSMSCOUT_BUILD_MAP_AGG_CACHE OFF)
endif()
option(OSMSCOUT_BUILD_MAP_AGG "Enable build of agg map drawing backend" ${OSMSCOUT_BUILD_MAP_AGG_CACHE})
if(OSMSCOUT_BUILD_MAP_AGG)
  if(NOT ${OSMSCOUT_BUILD_MAP})
    message(SEND_ERROR "The main map drawing interface is required for agg map drawing backend")
	set(OSMSCOUT_BUILD_MAP_AGG OFF)
  endif()
  if(NOT LIBAGG_FOUND)
    message(SEND_ERROR "libagg is required for agg map drawing backend")
	set(OSMSCOUT_BUILD_MAP_AGG OFF)
  endif()
  if(NOT LIBAGGFT2_LIBRARIES)
    message(SEND_ERROR "libaggft2 is required for agg map drawing backend")
	set(OSMSCOUT_BUILD_MAP_AGG OFF)
  endif()
  if(NOT FREETYPE_FOUND)
    message(SEND_ERROR "freetype2 is required for agg map drawing backend")
	set(OSMSCOUT_BUILD_MAP_AGG OFF)
  endif()
  if(OSMSCOUT_BUILD_MAP_AGG)
    add_subdirectory(libosmscout-map-agg)
  endif()
endif()

if(CAIRO_FOUND AND PNG_FOUND AND OSMSCOUT_BUILD_MAP)
  set(OSMSCOUT_BUILD_MAP_CAIRO_CACHE ON)
else()
  set(OSMSCOUT_BUILD_MAP_CAIRO_CACHE OFF)
endif()
option(OSMSCOUT_BUILD_MAP_CAIRO "Enable build of cairo map drawing backend" ${OSMSCOUT_BUILD_MAP_CAIRO_CACHE})
if(OSMSCOUT_BUILD_MAP_CAIRO)
  if(NOT ${OSMSCOUT_BUILD_MAP})
    message(SEND_ERROR "The main map drawing interface is required for cairo map drawing backend")
    set(OSMSCOUT_BUILD_MAP_CAIRO OFF)
  endif()
  if(NOT CAIRO_FOUND)
    message(SEND_ERROR "Cairo is required for cairo map drawing backend")
    set(OSMSCOUT_BUILD_MAP_CAIRO OFF)
  endif()
  if(NOT PNG_FOUND)
    message(SEND_ERROR "libpng is required for cairo map drawing backend")
    set(OSMSCOUT_BUILD_MAP_CAIRO OFF)
  endif()
  if(OSMSCOUT_BUILD_MAP_CAIRO)
    add_subdirectory(libosmscout-map-cairo)
  endif()
endif()

if(WIN32)
  if(Direct2D_FOUND AND OSMSCOUT_BUILD_MAP AND NOT MSYS)
    set(OSMSCOUT_BUILD_MAP_DIRECTX_CACHE ON)
  else()
    set(OSMSCOUT_BUILD_MAP_DIRECTX_CACHE OFF)
  endif()
  option(OSMSCOUT_BUILD_MAP_DIRECTX "Enable build of DirectX map drawing backend" ${OSMSCOUT_BUILD_MAP_DIRECTX_CACHE})
  option(OSMSCOUT_BUILD_MAP_GDI "Enable build of GDI+ map drawing backend" ON)
else()
  set(OSMSCOUT_BUILD_MAP_DIRECTX OFF)
  set(OSMSCOUT_BUILD_MAP_GDI OFF)
endif()
if(OSMSCOUT_BUILD_MAP_DIRECTX)
  if(NOT ${OSMSCOUT_BUILD_MAP})
    message(SEND_ERROR "The main map drawing interface is required for DirectX map drawing backend")
    set(OSMSCOUT_BUILD_MAP_DIRECTX OFF)
  endif()
  if(NOT Direct2D_FOUND)
    message(SEND_ERROR "Direct2D is required for DirectX map drawing backend")
    set(OSMSCOUT_BUILD_MAP_DIRECTX OFF)
  endif()
  if(OSMSCOUT_BUILD_MAP_DIRECTX)
    add_subdirectory(libosmscout-map-directx)
  endif()
endif()
if(OSMSCOUT_BUILD_MAP_GDI)
  if(NOT ${OSMSCOUT_BUILD_MAP})
    message(SEND_ERROR "The main map drawing interface is required for GDI+ map drawing backend")
    set(OSMSCOUT_BUILD_MAP_GDI OFF)
  endif()
  if(OSMSCOUT_BUILD_MAP_GDI)
    add_subdirectory(libosmscout-map-gdi)
  endif()
endif(OSMSCOUT_BUILD_MAP_GDI)

if(APPLE)
  option(OSMSCOUT_BUILD_MAP_IOSX "Enable build of iOS/OSX map drawing backend" ${OSMSCOUT_BUILD_MAP})
  if(OSMSCOUT_BUILD_MAP_IOSX)
    if(NOT ${OSMSCOUT_BUILD_MAP})
      message(SEND_ERROR "The main map drawing interface is required for cairo map drawing backend")
      set(OSMSCOUT_BUILD_MAP_IOSX OFF)
    endif()
    if(OSMSCOUT_BUILD_MAP_IOSX)
      add_subdirectory(libosmscout-map-iosx)
    endif()
  endif()
else()
  set(OSMSCOUT_BUILD_MAP_IOSX OFF CACHE INTERNAL "" FORCE)
endif()

if(OPENGL_FOUND AND GLEW_FOUND AND TARGET glm::glm AND PNG_FOUND AND OSMSCOUT_BUILD_MAP)
  set(OSMSCOUT_BUILD_MAP_OPENGL_CACHE ON)
else()
  set(OSMSCOUT_BUILD_MAP_OPENGL_CACHE OFF)
endif()
option(OSMSCOUT_BUILD_MAP_OPENGL "Enable build of OpenGL map drawing backend" ${OSMSCOUT_BUILD_MAP_OPENGL_CACHE})
if(OSMSCOUT_BUILD_MAP_OPENGL)
  if(NOT ${OSMSCOUT_BUILD_MAP})
    message(SEND_ERROR "The main map drawing interface is required for OpenGL map drawing backend")
	set(OSMSCOUT_BUILD_MAP_OPENGL OFF)
  endif()
  if(NOT PNG_FOUND)
    message(SEND_ERROR "libpng is required for OpenGL map drawing backend")
	set(OSMSCOUT_BUILD_MAP_OPENGL OFF)
  endif()
  if(NOT FREETYPE_FOUND)
    message(SEND_ERROR "freetype2 is required for OpenGL map drawing backend")
	set(OSMSCOUT_BUILD_MAP_OPENGL OFF)
  endif()
  if(NOT GLEW_FOUND)
    message(SEND_ERROR "GLEW is required for OpenGL map drawing backend")
	set(OSMSCOUT_BUILD_MAP_OPENGL OFF)
  endif()
  if(NOT TARGET glm::glm)
    message(SEND_ERROR "GLM is required for OpenGL map drawing backend")
	set(OSMSCOUT_BUILD_MAP_OPENGL OFF)
  endif()
  if(OSMSCOUT_BUILD_MAP_OPENGL)
    add_subdirectory(libosmscout-map-opengl)
  endif()
endif()

if(QT_MAP_DEPENDENCIES_FOUND AND OSMSCOUT_BUILD_MAP)
  set(OSMSCOUT_BUILD_MAP_QT_CACHE ON)
else()
  set(OSMSCOUT_BUILD_MAP_QT_CACHE OFF)
endif()
option(OSMSCOUT_BUILD_MAP_QT "Enable build of Qt map drawing backend" ${OSMSCOUT_BUILD_MAP_QT_CACHE})
if(OSMSCOUT_BUILD_MAP_QT)
  if(NOT ${OSMSCOUT_BUILD_MAP})
    message(SEND_ERROR "The main map drawing interface is required for QT map drawing backend")
    set(OSMSCOUT_BUILD_MAP_QT OFF)
  endif()
  if(OSMSCOUT_BUILD_MAP_QT)
    add_subdirectory(libosmscout-map-qt)
  endif()
endif()

option(OSMSCOUT_BUILD_MAP_SVG "Enable build of SVG map drawing backend" ${OSMSCOUT_BUILD_MAP})
if(OSMSCOUT_BUILD_MAP_SVG)
  if(NOT ${OSMSCOUT_BUILD_MAP})
    message(SEND_ERROR "The main map drawing interface is required for SVG map drawing backend")
    set(OSMSCOUT_BUILD_MAP_SVG OFF)
  endif()
  if(OSMSCOUT_BUILD_MAP_SVG)
    add_subdirectory(libosmscout-map-svg)
  endif()
endif()

option(OSMSCOUT_BUILD_CLIENT "Enable build of client library" ON)
if(OSMSCOUT_BUILD_CLIENT)
  add_subdirectory(libosmscout-client)
endif()

if(QT_CLIENT_DEPENDENCIES_FOUND)
  set(OSMSCOUT_BUILD_CLIENT_QT_CACHE ON)
else()
  set(OSMSCOUT_BUILD_CLIENT_QT_CACHE OFF)
endif()
option(OSMSCOUT_BUILD_CLIENT_QT "Enable build of Qt client library" ${OSMSCOUT_BUILD_CLIENT_QT_CACHE})
if(OSMSCOUT_BUILD_CLIENT_QT)
  if(NOT ${OSMSCOUT_BUILD_MAP})
    message(SEND_ERROR "The main map drawing interface is required for OSMScout Qt client library")
	set(OSMSCOUT_BUILD_CLIENT_QT OFF)
  endif()
  if(NOT ${OSMSCOUT_BUILD_MAP_QT})
    message(SEND_ERROR "The Qt map drawing interface is required for OSMScout Qt client library")
	set(OSMSCOUT_BUILD_CLIENT_QT OFF)
  endif()
  if(OSMSCOUT_BUILD_CLIENT_QT)
    add_subdirectory(libosmscout-client-qt)
  endif()
endif()

option(OSMSCOUT_BUILD_DEMOS "Enable build of demo applications" TRUE)
if(OSMSCOUT_BUILD_DEMOS)
  add_subdirectory(Demos)
endif()

option(OSMSCOUT_BUILD_TOOL_IMPORT "Enable build of import applications" ${OSMSCOUT_BUILD_IMPORT})
if(OSMSCOUT_BUILD_TOOL_IMPORT)
  add_subdirectory(Import)
  add_subdirectory(BasemapImport)
endif()

option(OSMSCOUT_BUILD_TOOL_DUMPDATA "Enable build of DumpData tool" TRUE)
if(OSMSCOUT_BUILD_TOOL_DUMPDATA)
  add_subdirectory(DumpData)
endif()

option(OSMSCOUT_BUILD_TOOL_PUBLICTRANSPORTMAP "Enable build of PublicTransportMap tool" TRUE)
if(OSMSCOUT_BUILD_TOOL_PUBLICTRANSPORTMAP)
  add_subdirectory(PublicTransportMap)
endif()

if(OSMSCOUT_BUILD_MAP_QT AND OSMSCOUT_BUILD_CLIENT_QT AND QT_CLIENT_DEPENDENCIES_FOUND)
  set(OSMSCOUT_BUILD_TOOL_OSMSCOUT2_CACHE ON)
else()
  set(OSMSCOUT_BUILD_TOOL_OSMSCOUT2_CACHE OFF)
endif()
option(OSMSCOUT_BUILD_TOOL_OSMSCOUT2 "Enable build of OSMSCout2 demo" ${OSMSCOUT_BUILD_TOOL_OSMSCOUT2_CACHE})
if(OSMSCOUT_BUILD_TOOL_OSMSCOUT2)
  if(NOT ${OSMSCOUT_BUILD_MAP_QT})
    message(SEND_ERROR "The Qt map drawing backend is required for OSMScout2 application")
	set(OSMSCOUT_BUILD_TOOL_OSMSCOUT2 OFF)
  endif()
  if(NOT ${OSMSCOUT_BUILD_CLIENT_QT})
    message(SEND_ERROR "The Qt client lib is required for OSMScout2 application")
	set(OSMSCOUT_BUILD_TOOL_OSMSCOUT2 OFF)
  endif()
  if(NOT ${OSMSCOUT_BUILD_GPX})
    message(SEND_ERROR "The Gpx lib is required for OSMScout2 application")
  	set(OSMSCOUT_BUILD_TOOL_OSMSCOUT2 OFF)
  endif()
  if(OSMSCOUT_BUILD_TOOL_OSMSCOUT2)
    add_subdirectory(OSMScout2)
  endif()
endif()

if(${OSMSCOUT_BUILD_MAP_OPENGL} AND TARGET glfw)
  set(OSMSCOUT_BUILD_TOOL_OSMSCOUTOPENGL_CACHE ON)
else()
  set(OSMSCOUT_BUILD_TOOL_OSMSCOUTOPENGL_CACHE OFF)
endif()
option(OSMSCOUT_BUILD_TOOL_OSMSCOUTOPENGL "Enable build of OSMScoutOpenGL applications" ${OSMSCOUT_BUILD_TOOL_OSMSCOUTOPENGL_CACHE})
if(OSMSCOUT_BUILD_TOOL_OSMSCOUTOPENGL)
  if(NOT ${OSMSCOUT_BUILD_MAP_OPENGL})
    message(SEND_ERROR "The OpenGL map drawing backend is required for OSMScoutOpenGL application")
	set(OSMSCOUT_BUILD_TOOL_OSMSCOUTOPENGL OFF)
  endif()
  if(NOT TARGET glfw)
    message(SEND_ERROR "GLFW is required for OSMScoutOpenGL application")
	set(OSMSCOUT_BUILD_TOOL_OSMSCOUTOPENGL OFF)
  endif()
  if(OSMSCOUT_BUILD_TOOL_OSMSCOUTOPENGL)
    add_subdirectory(OSMScoutOpenGL)
  endif()
endif()

if(OSMSCOUT_BUILD_MAP_QT AND OSMSCOUT_BUILD_CLIENT_QT AND QT_MAP_DEPENDENCIES_FOUND)
  set(OSMSCOUT_BUILD_TOOL_STYLEEDITOR_CACHE ON)
else()
  set(OSMSCOUT_BUILD_TOOL_STYLEEDITOR_CACHE OFF)
endif()
option(OSMSCOUT_BUILD_TOOL_STYLEEDITOR "Enable build of StyleEditor application" ${OSMSCOUT_BUILD_TOOL_STYLEEDITOR_CACHE})
if(OSMSCOUT_BUILD_TOOL_STYLEEDITOR)
  if(NOT ${OSMSCOUT_BUILD_MAP_QT})
    message(SEND_ERROR "The Qt map drawing backend is required for StyleEditor application")
    set(OSMSCOUT_BUILD_TOOL_STYLEEDITOR OFF)
  endif()
  if(NOT ${OSMSCOUT_BUILD_CLIENT_QT})
    message(SEND_ERROR "The Qt client lib is required for StyleEditor application")
    set(OSMSCOUT_BUILD_TOOL_STYLEEDITOR OFF)
  endif()
  if(OSMSCOUT_BUILD_TOOL_STYLEEDITOR)
    add_subdirectory(StyleEditor)
  endif()
endif()

if(DOXYGEN_FOUND)
  set(OSMSCOUT_BUILD_DOC_API_CACHE ON)
else()
  set(OSMSCOUT_BUILD_DOC_API_CACHE OFF)
endif()
option(OSMSCOUT_BUILD_DOC_API "Enable generation of api documentation" ${OSMSCOUT_BUILD_DOC_API_CACHE})
if(OSMSCOUT_BUILD_DOC_API)
  if(NOT DOXYGEN_FOUND)
    message(SEND_ERROR "Doxygen is required to build the documentation.")
  else()
    add_subdirectory(Documentation)
  endif()
endif()

if (HUGO_PATH)
  set(OSMSCOUT_BUILD_WEBPAGE_CACHE ON)
else()
  set(OSMSCOUT_BUILD_WEBPAGE_CACHE OFF)
endif()
option(OSMSCOUT_BUILD_WEBPAGE "Enable generation of webpage" ${OSMSCOUT_BUILD_WEBPAGE_CACHE})
if(OSMSCOUT_BUILD_WEBPAGE)
  add_subdirectory(webpage)
endif()

#if(SWIG_FOUND)
#  if(JNI_FOUND)
#    set(OSMSCOUT_BUILD_BINDING_JAVA_CACHE ON)
#  else()
#    set(OSMSCOUT_BUILD_BINDING_JAVA_CACHE OFF)
#  endif()
#  option(OSMSCOUT_BUILD_BINDING_JAVA "Enable generation of java binding" ${OSMSCOUT_BUILD_BINDING_JAVA_CACHE})
#  if(MSVC)
#    option(OSMSCOUT_BUILD_BINDING_CSHARP "Enable generation of c# binding" ON)
#  else()
#    set(OSMSCOUT_BUILD_BINDING_CSHARP OFF CACHE INTERNAL "CMake only supports Visual Studio with C#" FORCE)
#  endif()
#  if(PYTHONLIBS_FOUND)
#    set(OSMSCOUT_BUILD_BINDING_PYTHON_CACHE ON)
#  else()
#    set(OSMSCOUT_BUILD_BINDING_PYTHON_CACHE OFF)
#  endif()
#  option(OSMSCOUT_BUILD_BINDING_PYTHON "Enable generation of python binding" ${OSMSCOUT_BUILD_BINDING_PYTHON_CACHE})
#  add_subdirectory(libosmscout-binding)
#  add_subdirectory(libosmscout-map-binding)
#endif()

if(MATLAB_FOUND)
  set(OSMSCOUT_BUILD_EXTERN_MATLAB_CACHE ON)
else()
  set(OSMSCOUT_BUILD_EXTERN_MATLAB_CACHE OFF)
endif()
option(OSMSCOUT_BUILD_EXTERN_MATLAB "Enable generation of MATLAB mex function" ${OSMSCOUT_BUILD_EXTERN_MATLAB_CACHE})
add_subdirectory(libosmscout-extern)

# Tests
option(OSMSCOUT_BUILD_TESTS "Enable build of test applications" ON)
if(OSMSCOUT_BUILD_TESTS)
  enable_testing()
  add_subdirectory(libosmscout-test)
  if (TARGET Catch2::Catch2 AND TARGET Catch2::Catch2WithMain)
    add_subdirectory(Tests)
   else()
    message(STATUS "Disabled building of tests, since Catch2 dependency is not available")
  endif()
endif()

# display build configuration
message(STATUS)
message(STATUS "libosmscout ${PROJECT_VERSION} build configuration:")
message(STATUS "Shared libraries:                ${BUILD_SHARED_LIBS}")
if(APPLE)
  message(STATUS "Build frameworks:                ${BUILD_FRAMEWORKS}")
endif()
if(CCACHE_PROGRAM)
  message(STATUS "Using ccache:                    ${CCACHE_PROGRAM}")
endif()
message(STATUS)

message(STATUS "tests:                           ${OSMSCOUT_BUILD_TESTS}")
if (TARGET Catch2::Catch2)
  message(STATUS "- Catch2::Catch2                 TRUE")
else ()
  message(STATUS "- Catch2::Catch2                 FALSE")
endif ()
if (TARGET Catch2::Catch2WithMain)
  message(STATUS "- Catch2::Catch2WithMain         TRUE")
else ()
  message(STATUS "- Catch2::Catch2WithMain         FALSE")
endif ()
message(STATUS)

message(STATUS "Dependencies:")
if (TARGET glm::glm)
  message(STATUS "- glm:                           TRUE")
else ()
  message(STATUS "- glm:                           FALSE")
endif ()
if (TARGET glfw)
  message(STATUS "- glfw:                          TRUE")
else ()
  message(STATUS "- glfw:                          FALSE")
endif ()
if (TARGET harfbuzz::harfbuzz)
  message(STATUS "- harfbuzz:                      TRUE")
else ()
  message(STATUS "- harfbuzz:                      FALSE")
endif ()
if (TARGET LibLZMA::LibLZMA)
  message(STATUS "- LibLZMA:                       TRUE")
else ()
  message(STATUS "- LibLZMA:                       FALSE")
endif ()
if (TARGET LibXml2::LibXml2)
  message(STATUS "- LibXml2:                       TRUE")
else ()
  message(STATUS "- LibXml2:                       FALSE")
endif ()
if (TARGET protobuf::libprotobuf AND EXISTS ${PROTOBUF_PROTOC_EXECUTABLE})
  message(STATUS "- protobuf:                      TRUE")
else ()
  message(STATUS "- protobuf:                      FALSE")
endif ()
if (TARGET ZLIB::ZLIB)
  message(STATUS "- ZLIB:                          TRUE")
else ()
  message(STATUS "- ZLIB:                          FALSE")
endif ()
message(STATUS "")

message(STATUS "Qt5 libraries (${Qt5_FOUND}):")
message(STATUS " - Core:                         ${Qt5Core_FOUND}")
message(STATUS " - Svg:                          ${Qt5Svg_FOUND}")
message(STATUS " - Gui:                          ${Qt5Gui_FOUND}")
message(STATUS " - Widgets:                      ${Qt5Widgets_FOUND}")
message(STATUS " - Qml:                          ${Qt5Qml_FOUND}")
message(STATUS " - Quick:                        ${Qt5Quick_FOUND}")
message(STATUS " - Network:                      ${Qt5Network_FOUND}")
message(STATUS " - Location:                     ${Qt5Location_FOUND}")
message(STATUS " - Multimedia:                   ${Qt5Multimedia_FOUND}")
message(STATUS " - Positioning:                  ${Qt5Positioning_FOUND}")
message(STATUS " - LinguistTools:                ${Qt5LinguistTools_FOUND}")
message(STATUS)

message(STATUS "Qt6 libraries (${Qt6_FOUND}):")
message(STATUS " - Core:                         ${Qt6Core_FOUND}")
message(STATUS " - Core5Compat:                  ${Qt6Core5Compat_FOUND}")
message(STATUS " - Svg:                          ${Qt6Svg_FOUND}")
message(STATUS " - Gui:                          ${Qt6Gui_FOUND}")
message(STATUS " - Widgets:                      ${Qt6Widgets_FOUND}")
message(STATUS " - Qml:                          ${Qt6Qml_FOUND}")
message(STATUS " - Quick:                        ${Qt6Quick_FOUND}")
message(STATUS " - Network:                      ${Qt6Network_FOUND}")
message(STATUS " - Location:                     ${Qt6Location_FOUND}")
message(STATUS " - Multimedia:                   ${Qt6Multimedia_FOUND}")
message(STATUS " - Positioning:                  ${Qt6Positioning_FOUND}")
message(STATUS " - LinguistTools:                ${Qt6LinguistTools_FOUND}")
message(STATUS)

message(STATUS "Using Qt in version:             ${QT_VERSION_MAJOR}")
message(STATUS "Qt map dependencies found:       ${QT_MAP_DEPENDENCIES_FOUND}")
message(STATUS "Qt client dependencies found:    ${QT_CLIENT_DEPENDENCIES_FOUND}")
message(STATUS)

message(STATUS "core library:                    ${OSMSCOUT_BUILD_CORE}")
if (OSMSCOUT_BUILD_CORE)
  message(STATUS " - marisa support:               ${MARISA_FOUND}")
endif()
message(STATUS)

message(STATUS "import library:                  ${OSMSCOUT_BUILD_IMPORT}")
if (OSMSCOUT_BUILD_IMPORT)
  message(STATUS " - C++17 parallel execution:     ${HAVE_STD_EXECUTION}")
endif()
message(STATUS)

message(STATUS "gpx library:                     ${OSMSCOUT_BUILD_GPX}")
message(STATUS)

message(STATUS "map drawing interface:           ${OSMSCOUT_BUILD_MAP}")
message(STATUS " - Agg map drawing backend:      ${OSMSCOUT_BUILD_MAP_AGG}")
message(STATUS " - Cairo map drawing backend:    ${OSMSCOUT_BUILD_MAP_CAIRO}")
message(STATUS " - OpenGL map drawing backend:   ${OSMSCOUT_BUILD_MAP_OPENGL}")
message(STATUS " - DirectX map drawing backend:  ${OSMSCOUT_BUILD_MAP_DIRECTX}")
message(STATUS " - Qt map drawing backend:       ${OSMSCOUT_BUILD_MAP_QT}")
message(STATUS " - SVG map drawing backend:      ${OSMSCOUT_BUILD_MAP_SVG}")
message(STATUS " - OS X/iOS map drawing backend: ${OSMSCOUT_BUILD_MAP_IOSX}")
message(STATUS " - GDI+ map drawing backend:     ${OSMSCOUT_BUILD_MAP_GDI}")
message(STATUS)

message(STATUS "client libraries:")
message(STATUS " - Qt client library:            ${OSMSCOUT_BUILD_CLIENT_QT}")
message(STATUS)

message(STATUS "tools:")
message(STATUS " - Import/Import:                ${OSMSCOUT_BUILD_TOOL_IMPORT}")
message(STATUS " - Import/BasemapImport:         ${OSMSCOUT_BUILD_TOOL_IMPORT}")
message(STATUS " - DumpData:                     ${OSMSCOUT_BUILD_TOOL_DUMPDATA}")
message(STATUS " - OSMScout2:                    ${OSMSCOUT_BUILD_TOOL_OSMSCOUT2}")
message(STATUS " - OSMScoutOpenGL:               ${OSMSCOUT_BUILD_TOOL_OSMSCOUTOPENGL}")
message(STATUS " - StyleEditor:                  ${OSMSCOUT_BUILD_TOOL_STYLEEDITOR}")
message(STATUS)

message(STATUS "demos:                           ${OSMSCOUT_BUILD_DEMOS}")
message(STATUS " - heap profiler (Gperftools)    ${GPERFTOOLS_USAGE}")
message(STATUS)

message(STATUS "bindings:")
message(STATUS " - Java binding:                 ${OSMSCOUT_BUILD_BINDING_JAVA}")
message(STATUS " - C# binding:                   ${OSMSCOUT_BUILD_BINDING_CSHARP}")
message(STATUS)

message(STATUS "external interfaces:")
message(STATUS " - MATLAB mex function:          ${OSMSCOUT_BUILD_EXTERN_MATLAB}")
message(STATUS)

message(STATUS "doxygen:                         ${DOXYGEN_FOUND}")
message(STATUS "documentation:                   ${OSMSCOUT_BUILD_DOC_API}")
message(STATUS "webpage:                         ${OSMSCOUT_BUILD_WEBPAGE}")

install(DIRECTORY ${PROJECT_SOURCE_DIR}/stylesheets DESTINATION share/osmscout)
if(OSMSCOUT_INSTALL_QT_DLL AND TARGET Qt5::windeployqt)
	install(DIRECTORY "${CMAKE_BINARY_DIR}/windeployqt/" DESTINATION bin)
endif()

if(UNIX)
  set(config_install_dir "${CMAKE_INSTALL_PREFIX}/lib/cmake/${PROJECT_NAME}")
else()
  set(config_install_dir CMake)
endif()

set(version_config "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
set(project_config "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake")

include(CMakePackageConfigHelpers)

write_basic_package_version_file("${version_config}" COMPATIBILITY SameMajorVersion)
configure_package_config_file("cmake/libosmscoutConfig.cmake.in" "${project_config}" INSTALL_DESTINATION "${config_install_dir}")

install(FILES "${project_config}" "${version_config}" DESTINATION "${config_install_dir}")
